#pragma once

#include <functional>
#include <map>

#include "MessageParserTool.h"
#include "ProtoAdaptor.h"
#include "SSFilters.h"
#include "SSMsgStruct.h"
#include "extdef.h"
#include "message.h"

namespace qb {
struct AckMsgHead {
  short retcode;  // 标志: 0 成功，非0，执行失败，即错误代码
  char desc[40];  // 描述，请求成功信息，或者失败时的失败原因
  short total;    // 总包数，一般只有一个包填1
  short idx;      // 当前包序号，序号从0开始
  float exectime;  // 执行时间，单位秒数，如0.20秒
};
// class ConvertHub;

namespace proto {
class VariantRecord;
}

typedef std::function<void*(int, const ProtoMessage& msg, void* toDel)>
    DecodeFunc;

class SSPROTOAPI MessageParser {
 protected:
  bool JudgeJavaReturnInfo(const ProtoMessage& msg);
  void* ExtractData(int, const ProtoMessage& msg);

 public:
  MessageParser(void);
  ~MessageParser(void);

  void* DecodeMessage(SSAckMsg* pMsg);
  void SetDecodeFunc(DecodeFunc);

  int GetMessageType(const char* sBuffer, int nLen, SSAckMsg& stAckMsg);
  void Clean();
  int DecodeFilterMessage(const char* sBuffer, const size_t& nBufSize,
                          BondsFilter& filters);

  //==============================================================================
  // Summary:
  //     -获取当前已经解析后的消息
  // Parameters:
  //     -
  // Return:
  //     -
  // Remarks:
  //     -
  // Usage:
  //     -
  //==============================================================================
  bool GetCurrentMessage(int reqid, const ProtoMessage*& pmsg);
  bool GetCurrentHead(AckMsgHead& head);

 public:
  static const std::string TYPE;
  static const std::string SUBJECT;
  time_t m_lastReport;
  int nIsStillReceving;  // 1--正在收还有包；0--最后一个包，接收结束

  AckMsgHead msgheader;

 private:
  char* sMsgBuffer;
  int m_current_reqid;
  ProtoMessage msg;

  // 调试字段信息,仅供调试使用
  double m_time_clean;    // 当前消息解码的时间
  double m_time_decode;   //
  double m_time_extract;  //
  int m_msg_length;       // 当前消息的长度
  int m_funcid;           // 当前功能号码

  void ExtractHeader(const ProtoMessage& msg);
  DecodeFunc m_decodeFunc = nullptr;
};

}  // namespace qb
